import time
import random
import os
from StringIO import StringIO
import Image, ImageFont, ImageDraw

from django.utils.translation import ugettext_lazy as _
from django.http import HttpResponse
from django.conf import settings
from djwheel.langutils import update_object_attrs 

update_object_attrs(settings,
    CAPTCHA_SIZE = (120, 50),
    CAPTCHA_CODE_LENGTH = 4,
    CAPTCHA_LIFETIME = 20 * 60,
    CAPTCHA_SYMBOLS = '23458yRWxHAmNjFSie',
    CAPTCHA_COLOR = (0, 0, 0),
    CAPTCHA_BGCOLOR = (200, 200, 200),
)

class Captcha(object):
    SESSION_KEY = 'Captcha'
    FORMAT = 'png'
    
    def __init__(self, request, request_id=0):
        self.request_id = request_id
        self.session = request.session        

    def regenerate(self):
        """Regenerate captcha code"""
        ts = time.time()
        code = ''.join(random.choice(settings.CAPTCHA_SYMBOLS) for i in xrange(settings.CAPTCHA_CODE_LENGTH))
        
        if self.SESSION_KEY not in self.session:
            self.session[self.SESSION_KEY] = {}        
        
        self.session[self.SESSION_KEY][self.request_id] = ts, code
        self.session.save()
                
        time.sleep(1)
        return code

    def check(self, entered_code):
        """Check code for errors. Raise CheckCaptchaError."""
        storage = self.session.get(self.SESSION_KEY, {})
        
        if self.request_id not in storage:
            self.regenerate()
            raise CheckCaptchaError, _('Picture is osolete. Try again')

        ts, code = storage[self.request_id]
        if (time.time() - ts) > settings.CAPTCHA_LIFETIME:
            self.regenerate()
            raise CheckCaptchaError, _('Picture is osolete. Try again')
        
        if code and entered_code.lower() != code.lower():
            self.regenerate()
            raise CheckCaptchaError, _('Incorrect code')                    
        
    def output(self):
        """Return HttpResponse object with captcha image"""
        code = self.regenerate()
        
        im = Image.new('RGB', settings.CAPTCHA_SIZE, settings.CAPTCHA_BGCOLOR)
        
        self._write_digits(im, code)
        self._distort(im)
        
        out = StringIO()
        im.save(out, self.FORMAT)
        out.seek(0)
        
        return HttpResponse(out.read(), content_type='image/%s' % self.FORMAT)
                    
    def _write_digits(self, im, code):
        #fontpath = '%s/%s' % (os.path.dirname(__file__), 'ff.ttf') 
        #font = ImageFont.truetype(fontpath, 19)
        font = ImageFont.load_default() 
        draw = ImageDraw.Draw(im)
#        # Draw the text, starting from (2,2) so the text won't be edge
        draw.text((2, 2), code, font=font, fill=settings.CAPTCHA_COLOR)                        
        pass
#        $arrFonts = Dir::getFiles($this->getFontsDir(), '*.ttf');
#
#        if (!$arrFonts)
#            throw new Exception('no fonts!');
#
#        $minFontSize = $this->getHeight() * 0.30;
#        $maxFontSize = $this->getHeight() * 0.58;
#
#        $minColorBrightnessWord = 100;
#        $maxColorBrightnessWord = 150;
#
#        for ($i = 0; $i < self::CODE_LENGTH; $i++) {
#
#            $angle = mt_rand(-10, 10);
#            $size = mt_rand($minFontSize,$maxFontSize);
#            $margin = 10;
#
#            $x = round($margin * 1.3 + ($i / self::CODE_LENGTH) * ($this->getWidth() - $margin * 2) );
#            $y = round($this->getHeight() / 2 + $size / 2);
#
#            $color = $this->getGrayColor($im, mt_rand($minColorBrightnessWord, $maxColorBrightnessWord));
#            $font = $arrFonts[mt_rand(0, count($arrFonts) - 1)];
#
#            imagettftext($im, $size, $angle, $x, $y, $color, $font, $code[$i]);
#        }
#
#        imagepng($im);
#        imagedestroy($im); 

    def _distort(self, im):
        pass
#        $minLineLength = 10;
#        $maxLineLength = 300;
#
#        $linesNumber = round(0.5 * $this->getWidth() * $this->getHeight() / (($maxLineLength - $minLineLength) / 2));
#
#        $minColorBrightnessLine = 150;
#        $maxColorBrightnessLine = 200;
#
#        $maxColorBrightnessLine = 200;
#
#        for ($i = 0; $i < $linesNumber; $i++) {
#
#            imagesetthickness($im, round($i / $linesNumber * 2 + 1));
#
#            $linesLength = mt_rand($maxLineLength, $maxLineLength);
#
#            $y1 = mt_rand(0, $this->getHeight());
#            $x1 = mt_rand(0, $this->getWidth());
#
#            $x2 = mt_rand($x1 - $linesLength, $x1 + $linesLength);
#            $y2 = mt_rand($y1 - $linesLength, $y1 + $linesLength);
#
#            $color = $this->getGrayColor($im, mt_rand($minColorBrightnessLine, $maxColorBrightnessLine));
#
#            imageline($im, $x1, $y1, $x2, $y2, $color);
#        }
#    }

class CheckCaptchaError(Exception): 
    pass
